﻿using Futajma.MigrationStudio.DataDefinition;
using Futajma.MigrationStudio.LiveLinkImporter.Data;
using Futajma.MigrationStudio.LiveLinkImporter.Tdx;
using Futajma.MigrationStudio.LiveLinkImporter.TreeActions;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using LDATA = Futajma.MigrationStudio.LiveLinkImporter.Data;
using Futajma.MigrationStudio.CommonLib;
using Futajma.MigrationStudio.LiveLinkImporter;
using Futajma.MigrationStudio.GenericImporter;
using OfficeOpenXml;
using System.Reflection;

namespace Futajma.MigrationStudio.LiveLinkImporter
{
    [ObfuscationAttribute(Exclude = true, ApplyToMembers = false)]
    public class LiveLinkFileImporter : GenericImporter.IImporter
    {
        #region MemberVariables
        const int PROGRESS_FACTOR = 10;
        Dictionary<string, XmlDocument> _separateDataFiles = new Dictionary<string, XmlDocument>();
        string _filePath = string.Empty;
        string _dataFilesFolder = string.Empty;

        int _folderNodeCount = 0;
        int _currentNodeCount = 0;
        #endregion

        public event ProgressUpdate ProgressUpdate;

        public event ProgressInit ProgressInit;

        //public event ProgressUpdateDone ProgressUpdateDone;

        void SendProgressUpdate(long currentStep)
        {
            if (ProgressUpdate != null)
            {
                ProgressUpdate(this, currentStep);
            }
        }

        void SendProgressInit(long stepCount, string name)
        {
            if (ProgressInit != null)
            {
                ProgressInit(this, stepCount, name);
            }
        }

        #region Private Methods
        private void BuildNode(XmlNode xmlNode, TreeNode node, string path, int currentVersion, bool loadItems = true)
        {
            XmlNodeList nodeList = xmlNode.SelectNodes("folder");

            if (_currentNodeCount % PROGRESS_FACTOR == 0)
            {
                SendProgressUpdate(_currentNodeCount);
            }

            _currentNodeCount++;

            if (nodeList.Count > 0)
            {
                foreach (XmlNode childNode in nodeList)
                {
                    var name = childNode.Attributes["name"].Value;

                    var type = childNode.SelectSingleNode("properties/property[@ref='itemType']");

                    var val = 0;

                    if (type == null)
                    {
                        Console.WriteLine(string.Format("LiveLink Type not defined {0}.", name));
                        //val = 0;
                    }
                    else
                    {
                        val = int.Parse(type.InnerText);
                    }

                    var index = GetIconIndex((LiveLinkType)val);

                    //var realName = string.IsNullOrEmpty(name) ? "unknow" : name;
                    //realName = realName.Replace('+', ' ');

                    //var newName = System.Web.HttpUtility.HtmlEncode(realName);

                    LDATA.DataNode dataNode = CreateDataNode(childNode, node, currentVersion);

                    var treeNode = new TreeNode(dataNode.Title, index, index);
                    treeNode.Tag = dataNode;
                    node.Nodes.Add(treeNode);

                    var folders = childNode.SelectSingleNode("folders");

                    if (folders != null)
                    {
                        BuildNode(folders, treeNode, path, currentVersion, loadItems);
                    }

                    if (loadItems)
                    {
                        BuildDocumentNodes(childNode, treeNode, path, currentVersion);
                    }

                }
            }
            //else
            //{
            //    node.Text = (xmlNode.OuterXml).Trim();
            //}
        }

        private void BuildDocumentNodes(XmlNode childNode, TreeNode treeNode, string path, int currentVersion)
        {
            if (childNode.Attributes["itemsFile"] != null)
            {
                var itemsFile = childNode.Attributes["itemsFile"].Value;
                var file = string.Format(@"{0}\{1}", path, itemsFile);

                var folderName = childNode.Attributes["href"].Value;

                if (!string.IsNullOrEmpty(folderName) && !string.IsNullOrEmpty(itemsFile) && File.Exists(file))
                {
                    XmlDocument doc = null;

                    if (_separateDataFiles.ContainsKey(itemsFile))
                    {
                        doc = _separateDataFiles[itemsFile];
                    }
                    else
                    {
                        doc = new XmlDocument();
                        doc.Load(file);
                        _separateDataFiles.Add(itemsFile, doc);
                    }

                    #region Documents

                    var documents = doc.DocumentElement.SelectNodes(string.Format("//documents/document[@folderRef='{0}']", folderName));

                    foreach (XmlNode docNode in documents)
                    {
                        //var name = docNode.Attributes["name"].Value;

                        //var realName = string.IsNullOrEmpty(name) ? "unknow" : name;
                        //realName = realName.Replace('+', ' ');

                        #region LoadData



                        var fileSize = docNode.SelectSingleNode("properties/property[@ref='fileSize']");
                        var liveLinkId = docNode.SelectSingleNode("properties/property[@ref='liveLinkId']");
                        var itemType = docNode.SelectSingleNode("properties/property[@ref='itemType']");
                        var name = docNode.SelectSingleNode("properties/property[@ref='title']").InnerText;

                        if (!CheckIfVersionInNodeExists(treeNode, name))
                        {
                            LDATA.DataNode dataNode = CreateDataNode(docNode, treeNode, currentVersion);

                            dataNode.ItemCount = 1;

                            if (fileSize != null)
                            {
                                var fileSizeStr = fileSize.InnerText;
                                dataNode.FileSize = string.IsNullOrEmpty(fileSizeStr) ? 0 : int.Parse(fileSizeStr);
                            }

                            if (liveLinkId != null)
                            {
                                var liveLinkIdStr = liveLinkId.InnerText;
                                dataNode.SourceId = string.IsNullOrEmpty(liveLinkIdStr) ? "0" : liveLinkIdStr;
                            }

                            var itemTypeId = 5;

                            if (itemType != null)
                            {
                                var itemTypeStr = itemType.InnerText;

                                itemTypeId = string.IsNullOrEmpty(itemTypeStr) ? 0 : int.Parse(itemTypeStr);
                            }
                            else
                            {
                                Console.WriteLine(string.Format("LiveLink Type not defined {0}.", name));
                            }

                            var index = GetIconIndex((LiveLinkType)itemTypeId);
                            var newNode = new TreeNode(name, index, index);
                            //newNode.Text = "";
                            treeNode.Nodes.Add(newNode);

                            newNode.Tag = dataNode;
                        }
                        #endregion
                    }
                    #endregion

                    #region Items

                    var items = doc.DocumentElement.SelectNodes(string.Format("//dataItems/dataItem[@folderRef='{0}']", folderName));

                    foreach (XmlNode docNode in items)
                    {
                        //var name = docNode.Attributes["name"].Value;

                        //var realName = string.IsNullOrEmpty(name) ? "unknow" : name;
                        //realName = realName.Replace('+', ' ');

                        #region LoadData



                        //var fileSize = docNode.SelectSingleNode("properties/property[@ref='fileSize']");
                        var liveLinkId = docNode.SelectSingleNode("properties/property[@ref='liveLinkId']");
                        var itemType = docNode.SelectSingleNode("properties/property[@ref='itemType']");
                        var name = docNode.SelectSingleNode("properties/property[@ref='title']").InnerText;

                        if (!CheckIfVersionInNodeExists(treeNode, name))
                        {


                            LDATA.DataNode dataNode = CreateDataNode(docNode, treeNode, currentVersion);
                            //if (fileSize != null)
                            //{
                            //    var fileSizeStr = fileSize.InnerText;
                            //    dataNode.FileSize = string.IsNullOrEmpty(fileSizeStr) ? 0 : int.Parse(fileSizeStr);
                            //}

                            if (liveLinkId != null)
                            {
                                var liveLinkIdStr = liveLinkId.InnerText;
                                dataNode.SourceId = string.IsNullOrEmpty(liveLinkIdStr) ? "0" : liveLinkIdStr;
                            }

                            var itemTypeId = 5;

                            if (itemType != null)
                            {
                                var itemTypeStr = itemType.InnerText;

                                itemTypeId = string.IsNullOrEmpty(itemTypeStr) ? 0 : int.Parse(itemTypeStr);
                            }
                            else
                            {
                                Console.WriteLine(string.Format("LiveLink Type not defined {0}.", name));
                            }

                            var index = GetIconIndex((LiveLinkType)itemTypeId);
                            var newNode = new TreeNode(name, index, index);
                            treeNode.Nodes.Add(newNode);

                            newNode.Tag = dataNode;
                        #endregion
                        }
                    }
                    #endregion
                }
            }
        }

        private bool CheckIfVersionInNodeExists(TreeNode treeNode, string name)
        {
            bool found = false;

            foreach (TreeNode child in treeNode.Nodes)
            {
                if (child.Text == name)
                {
                    found = true;
                    break;
                }
            }
            return found;
        }

        private LDATA.DataNode CreateDataNode(Futajma.MigrationStudio.LiveLinkImporter.Tdx.Item item, TreeNode parentNode, int currentVersion)
        {
            var parentDataNode = parentNode.Tag as LiveLinkImporter.Data.DataNode;
            var sourcePath = string.Empty;

            if (parentDataNode != null)
            {
                sourcePath = string.Format("{0}/{1}", parentDataNode.SourcePath, item.Title);
            }
            else
            {
                sourcePath = string.Format("{0}/{1}", CreatePath(parentNode), item.Title);
            }

            var dataNode = new LiveLinkImporter.Data.DataNode() { Title = item.Title, SourcePath = sourcePath, LiveLinkType = item.LiveLinkType, SourceId = item.LiveLinkId, SourceUrl = System.Web.HttpUtility.UrlDecode(item.GetStringAttribute("href")) };

            dataNode.SharePointType = GetSharePointType(dataNode.LiveLinkType);
            dataNode.Version = currentVersion;
            dataNode.PreviousVersion = 0;

            return dataNode;
        }

        private LDATA.DataNode CreateDataNode(XmlNode xmlNode, TreeNode parentNode, int currentVersion)
        {
            var name = xmlNode.Attributes["name"].Value;
            name = System.Web.HttpUtility.UrlDecode(name);
            var liveLinkUrl = xmlNode.Attributes["href"].Value;
            //var sourcePath = xmlNode.Attributes["href"].Value;
            //sourcePath = System.Web.HttpUtility.HtmlEncode(sourcePath);

            var sourcePath = string.Empty;// CreatePath(parentNode);

            var type = xmlNode.SelectSingleNode("properties/property[@ref='itemType']");
            var liveLinkIdNode = xmlNode.SelectSingleNode("properties/property[@ref='liveLinkId']");
            //var name = xmlNode.SelectSingleNode("properties/property[@ref='title']").InnerText;
            //var liveLinkUrlNode = xmlNode.SelectSingleNode("properties/property[@ref='downloadUrl']");

            var typeVal = type == null ? "0" : type.InnerText;

            var val = int.Parse(typeVal);
            var liveLinkId = 0;

            if (liveLinkIdNode != null)
            {
                var liveLinkIdStr = liveLinkIdNode.InnerText;
                liveLinkId = string.IsNullOrEmpty(liveLinkIdStr) ? 0 : int.Parse(liveLinkIdStr);
            }

            //name = string.IsNullOrEmpty(name) ? "unknow" : name;
            //var liveLinkUrl = liveLinkUrlNode != null ? liveLinkUrlNode.InnerText : "";

            liveLinkUrl = System.Web.HttpUtility.UrlDecode(liveLinkUrl);
            name = System.Web.HttpUtility.UrlDecode(name);

            var parentDateNode = parentNode.Tag as LiveLinkImporter.Data.DataNode;

            if (parentDateNode != null)
            {
                sourcePath = string.Format("{0}/{1}", parentDateNode.SourcePath, name);
            }
            else
            {
                sourcePath = string.Format("{0}/{1}", CreatePath(parentNode), name);
            }

            var dataNode = new LiveLinkImporter.Data.DataNode() { Title = name, SourcePath = sourcePath, LiveLinkType = (LiveLinkType)val, SourceId = liveLinkId.ToString("d"), SourceUrl = liveLinkUrl };

            dataNode.SharePointType = GetSharePointType(dataNode.LiveLinkType);
            dataNode.Version = currentVersion;
            dataNode.PreviousVersion = 0;

            return dataNode;
        }

        private string CreatePath(TreeNode node)
        {
            if (node.Parent == null)
            {
                return string.Empty;
            }
            else
            {
                return string.Format("{0}/{1}", CreatePath(node.Parent), node.Text);
            }
        }

        private SharePointType GetSharePointType(LiveLinkType liveLinkType)
        {
            SharePointType type = SharePointType.NotDefined;

            switch (liveLinkType)
            {
                case LiveLinkType.Document:
                case LiveLinkType.TextDocument:
                    type = SharePointType.Document;
                    break;
                case LiveLinkType.Folder:
                case LiveLinkType.CompoundDocument:
                    type = SharePointType.Folder;
                    break;
                case LiveLinkType.Item:
                case LiveLinkType.Alias:
                case LiveLinkType.URL:
                    type = SharePointType.Item;
                    break;
                case LiveLinkType.Project:
                    type = SharePointType.SiteCollection;
                    break;
                default:
                    type = SharePointType.Document;
                    Console.WriteLine(string.Format("Unknown LiveLink Type {0}.", liveLinkType));
                    break;
            }

            return type;
        }

        private int GetIconIndex(LiveLinkType liveLinkType)
        {
            int value = 0;

            switch (liveLinkType)
            {
                case LiveLinkType.Document:
                    value = 5;
                    break;
                case LiveLinkType.TextDocument:
                    value = 6;
                    break;
                case LiveLinkType.URL:
                    value = 4;
                    break;
                case LiveLinkType.Folder:
                    value = 1;
                    break;
                case LiveLinkType.CompoundDocument:
                    value = 3;
                    break;
                case LiveLinkType.Project:
                    value = 7;
                    break;
                case LiveLinkType.Alias:
                    value = 2;
                    break;
            }
            return value;
        }
        #endregion

        [ObfuscationAttribute(Exclude = true)]
        public ImageList GetImageListList()
        {
            ImageList myImageList = new ImageList();
            myImageList.Images.Add(TypeIcons.LiveLink);
            myImageList.Images.Add(TypeIcons._0_folder);
            myImageList.Images.Add(TypeIcons._1_alias);
            myImageList.Images.Add(TypeIcons._136_cd);
            myImageList.Images.Add(TypeIcons._140_url);
            myImageList.Images.Add(TypeIcons._144_doc);
            myImageList.Images.Add(TypeIcons._145_apptext);
            myImageList.Images.Add(TypeIcons._202_project);
            return myImageList;
        }

        [ObfuscationAttribute(Exclude = true)]
        public SharePointType GetSharePointType(DataDefinition.DataNode dataNode)
        {
            var data = dataNode as LiveLinkImporter.Data.DataNode;

            if (data != null)
            {
                return GetSharePointType(data.LiveLinkType);
            }

            return SharePointType.NotDefined;
        }

        [ObfuscationAttribute(Exclude = true)]
        public DataDefinition.DataNode GetNewDataNode(int currentProjectVersion)
        {
            return new LDATA.DataNode() { LiveLinkType = LiveLinkType.Undefined, Version = currentProjectVersion, PreviousVersion = 0 };
        }

        XmlSerializer _serializer = new XmlSerializer(typeof(LDATA.DataNode));

        [ObfuscationAttribute(Exclude = true)]
        public System.Xml.Serialization.XmlSerializer GetXmlSerializer()
        {
            //return new XmlSerializer(typeof(LDATA.DataNode));
            return _serializer;
        }

        [ObfuscationAttribute(Exclude = true)]
        public DialogResult ShowDialog()
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.RestoreDirectory = true;
            dlg.Filter = "Tzunami Exporter File|*.tdx";
            dlg.Title = "Select a Tzunami Exporter File";

            var ret = dlg.ShowDialog();

            if (ret == System.Windows.Forms.DialogResult.OK)
            {
                _dataFilesFolder = Path.GetDirectoryName(dlg.FileName);
                _filePath = string.Format(@"{0}\{1}", _dataFilesFolder, dlg.SafeFileName);
            }

            return ret;
        }

        #region Delta Update
        [ObfuscationAttribute(Exclude = true)]
        public Dictionary<string, UpdateResult> DeltaUpdate(TreeView sourceTree, TreeView targetTree, int currentVersion)
        {
            return DeltaUpdateInternal(sourceTree, targetTree, currentVersion);
        }

        private Dictionary<string, UpdateResult> DeltaUpdateInternal(TreeView sourceTree, TreeView targetTree, int currentVersion)
        {
            var resultList = new Dictionary<string, UpdateResult>();

            if (!string.IsNullOrEmpty(_filePath))
            {
                sourceTree.ImageList = GetImageListList();
                var tdx = new TDX();
                tdx.Load(_filePath);
                _currentNodeCount = 0;
                SendProgressInit(tdx.GetFlattenItemList().Count, "Load and extract delta migration.");
                // Generate new source tree
                TreeNode sourceRootNode = sourceTree.Nodes[0];
                TreeNode targetRootNode = targetTree.Nodes[0];

                var treeData = new TreeData();
                treeData.PopulateTrees(sourceTree, targetTree);

                foreach (var folder in tdx.Folders())
                {
                    ReorgOrCreateFolderNode(treeData, sourceRootNode, sourceRootNode, targetRootNode, folder, currentVersion, resultList);
                }
            }
            return resultList;
        }

        private void ReorgOrCreateFolderNode(TreeData treeData, TreeNode sourceNode, TreeNode sourceRootNode, TreeNode targetRootNode, Folder folder, int currentVersion, Dictionary<string, UpdateResult> resultList)
        {
            var foundNode = treeData.GetSourceNode(folder.LiveLinkId);
            //var targetNode = TreeData.FindNode(targetRootNode, item.LiveLinkId);

            UpdateResult updateResult = UpdateResult.NoAction;
            string path = string.Empty;

            if (foundNode != null)
            {
                // folder existing

                if (foundNode.Parent != sourceNode)
                {
                    foundNode.Parent.Nodes.Remove(foundNode);
                    sourceNode.Nodes.Add(foundNode);
                    updateResult |= UpdateResult.InSourceRelocated;
                }

                if (foundNode.Text != folder.Title)
                {
                    updateResult |= UpdateResult.RenamedInSource;
                }

                foundNode.Text = folder.Title;
                var data = foundNode.Tag as DataDefinition.DataNode;
                data.Title = folder.Title;
                data.PreviousVersion = data.Version;
                data.Version = currentVersion;
                path = data.SourcePath;

                var targetNode = treeData.GetTargetNode(folder.LiveLinkId);
                if (targetNode != null)
                {
                    if (updateResult != UpdateResult.NoAction)
                    {
                        var targetData = targetNode.Tag as DataDefinition.DataNode;
                        targetData.PreviousVersion = targetData.Version;
                        targetData.Version = currentVersion;
                        updateResult |= UpdateResult.NewVersionInTargetAdded;
                    }
                }
                else
                {
                    data.CommitedItem = false;
                    updateResult |= UpdateResult.FoundInSourceNotMapped;
                }
            }
            else
            {
                // create a new folder
                var index = GetIconIndex(folder.LiveLinkType);

                LDATA.DataNode dataNode = CreateDataNode(folder, sourceNode, currentVersion);
                foundNode = new TreeNode(dataNode.Title, index, index);
                foundNode.Tag = dataNode;
                sourceNode.Nodes.Add(foundNode);
                treeData.AddSourceNode(foundNode);
                updateResult |= UpdateResult.NewCreatedInSource;
                path = dataNode.SourcePath;
            }

            if (resultList.ContainsKey(path))
            {
                resultList.Add(resultList.Count + "_" + path, updateResult);
            }
            else
            {
                resultList.Add(path, updateResult);
            }

            foreach (var subFolder in folder.SubFolders())
            {
                ReorgOrCreateFolderNode(treeData, foundNode, sourceRootNode, targetRootNode, subFolder, currentVersion, resultList);
            }

            foreach (var item in folder.GetItems())
            {
                ReorgOrCreateItemNode(treeData, item, foundNode, sourceRootNode, targetRootNode, currentVersion, resultList);
            }

        }

        private void ReorgOrCreateItemNode(TreeData treeData, Item item, TreeNode folderNode, TreeNode sourceRootNode, TreeNode targetRootNode, int currentVersion, Dictionary<string, UpdateResult> resultList)
        {
            var foundNode = treeData.GetSourceNode(item.LiveLinkId);
            UpdateResult updateResult = UpdateResult.NoAction;
            string path = string.Empty;

            if (foundNode != null)
            {
                if (foundNode.Text != item.Title)
                {
                    updateResult = UpdateResult.RenamedInSource;
                }

                // item existing
                foundNode.Text = item.Title;
                var data = foundNode.Tag as DataDefinition.DataNode;
                data.Title = item.Title;
                data.FileSize = item.FileSize;
                data.PreviousVersion = data.Version;
                data.Version = currentVersion;
                path = data.SourcePath;

                var targetNode = treeData.GetTargetNode(item.LiveLinkId);
                if (targetNode != null)
                {
                    var targetData = targetNode.Tag as DataDefinition.DataNode;
                    targetData.PreviousVersion = targetData.Version;
                    targetData.Version = currentVersion;
                    updateResult |= UpdateResult.NewVersionInTargetAdded;
                }
                else
                {
                    data.CommitedItem = false;
                    updateResult |= UpdateResult.FoundInSourceNotMapped;
                }
            }
            else
            {
                // create a new item
                var index = GetIconIndex(item.LiveLinkType);

                LDATA.DataNode dataNode = CreateDataNode(item, folderNode, 0);
                dataNode.Version = currentVersion;
                dataNode.FileSize = item.FileSize;
                foundNode = new TreeNode(dataNode.Title, index, index);
                foundNode.Tag = dataNode;
                folderNode.Nodes.Add(foundNode);
                treeData.AddSourceNode(foundNode);
                updateResult |= UpdateResult.NewCreatedInSource;
                path = dataNode.SourcePath;
            }

            if (!resultList.ContainsKey(path))
            {
                resultList.Add(path, updateResult);
            }

            if (_currentNodeCount % PROGRESS_FACTOR == 0)
            {
                SendProgressUpdate(_currentNodeCount);
            }

            _currentNodeCount++;
        }

        private void ProcessNodeRecursive(TreeNode node, TDX tdx, int currentVersion)
        {
            DataDefinition.DataNode data = node.Tag as DataDefinition.DataNode;

            if (data != null && data.SourceId != null)
            {
                if (tdx.GetFlattenFolders().ContainsKey(data.SourceId))
                {
                    var folder = tdx.GetFlattenFolders()[data.SourceId];

                    var title = tdx.GetTitle(folder);

                    if (title == data.Title)
                    {
                        data.PreviousVersion = data.Version;
                        data.Version = currentVersion;
                        tdx.GetFlattenFolders().Remove(data.SourceId);
                    }
                }
                else if (tdx.GetFlattenItemList().ContainsKey(data.SourceId))
                {
                    var item = tdx.GetFlattenItemList()[data.SourceId][0];

                    var title = tdx.GetTitle(item);

                    if (title == data.Title)
                    {
                        data.PreviousVersion = data.Version;
                        data.Version = currentVersion;
                        tdx.GetFlattenItemList().Remove(data.SourceId);
                    }
                }
            }

            foreach (TreeNode child in node.Nodes)
            {
                ProcessNodeRecursive(child, tdx, currentVersion);
            }
        }

        [ObfuscationAttribute(Exclude = true)]
        public void SaveUpdateResult(Dictionary<string, UpdateResult> resultList, string path)
        {
            SaveUpdateResultInternal(resultList, path);
        }

        private void SaveUpdateResultInternal(Dictionary<string, UpdateResult> resultList, string path)
        {
            using (var saveFileInfo = new FileStream(path, FileMode.Create))
            {
                using (var excel = new ExcelPackage(saveFileInfo))
                {
                    ExcelWorksheet worksheet = excel.Workbook.Worksheets.Add("Report");

                    int row = 1;

                    foreach (var key in resultList.Keys)
                    {
                        var result = resultList[key];

                        worksheet.Cells[row, 1].Value = key;

                        string res = GetResultString(result);

                        worksheet.Cells[row, 2].Value = res;

                        string action = GetActionString(result);
                        worksheet.Cells[row, 3].Value = action;
                        row++;
                    }
                    excel.Save();
                    excel.Dispose();
                }
                saveFileInfo.Dispose();
            }
        }

        private string GetActionString(UpdateResult updateResult)
        {
            string res = "No action needed";

            if ((updateResult & UpdateResult.NewCreatedInSource) == UpdateResult.NewCreatedInSource)
            {
                res = "Action needed";
            }
            if ((updateResult & UpdateResult.FoundInSourceNotMapped) == UpdateResult.FoundInSourceNotMapped)
            {
                res = "Action needed";
            }

            return res;
        }

        private string GetResultString(UpdateResult updateResult)
        {
            string res = string.Empty;

            if ((updateResult & UpdateResult.FoundInSourceNotMapped) == UpdateResult.FoundInSourceNotMapped)
            {
                res = "Item found in update, but not mapped to target yet;";
            }
            if ((updateResult & UpdateResult.InSourceRelocated) == UpdateResult.InSourceRelocated)
            {
                res += "Item in source relocated;";
            }
            if ((updateResult & UpdateResult.NewCreatedInSource) == UpdateResult.NewCreatedInSource)
            {
                res = "In source as new item added;";
            }
            if ((updateResult & UpdateResult.NewVersionInTargetAdded) == UpdateResult.NewVersionInTargetAdded)
            {
                res = "New version to targed assigned;";
            }
            //if ((updateResult & UpdateResult.NoAction) == UpdateResult.NoAction)
            //{
            //    res = "Nothing happends, please check with support;";
            //}
            if ((updateResult & UpdateResult.RenamedInSource) == UpdateResult.RenamedInSource)
            {
                res = "Item title different in source and target.";
            }

            return res;
        }

        #endregion

        [ObfuscationAttribute(Exclude = true)]
        public void Import(TreeView tree, int currentVersion, bool loadItems = true)
        {
            ImportInternal(tree, currentVersion, loadItems);
        }

        private void ImportInternal(TreeView tree, int currentVersion, bool loadItems = true)
        {
            tree.Nodes.Clear();

            if (!string.IsNullOrEmpty(_filePath))
            {

                tree.ImageList = GetImageListList();

                var rootNode = new TreeNode(ConfigurationManager.AppSettings["SourceTreeRootTitle"], 0, 0);
                LDATA.DataNode dataNodeLL = new LDATA.DataNode() { Title = "LiveLink tree", LiveLinkType = 0 };
                rootNode.Tag = dataNodeLL;
                tree.Nodes.Add(rootNode);

                var doc = new XmlDocument();
                doc.Load(_filePath);
                var folders = doc.DocumentElement.SelectSingleNode("folders");

                var path = Path.GetDirectoryName(_filePath);

                _folderNodeCount = folders.SelectNodes("//folders").Count;
                _currentNodeCount = 0;
                _separateDataFiles.Clear();

                SendProgressInit(_folderNodeCount, "Build LiveLink tree");

                BuildNode(folders, rootNode, path, currentVersion, loadItems);
            }
        }

        public void SetConfiguration(object configuration)
        {
            string config = configuration as string;

            if (!string.IsNullOrEmpty(config))
            {
                _dataFilesFolder = Path.GetDirectoryName(config);
                _filePath = config;
            }
        }

        public event ProgressUpdateDone ProgressUpdateDone;

        [ObfuscationAttribute(Exclude = true)]
        public void ImportDeploymentReport(TreeView targetTreeView, int version)
        {
            ImportDeploymentReportInternal(targetTreeView, version);
        }

        private void ImportDeploymentReportInternal(TreeView targetTreeView, int version)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                dlg.RestoreDirectory = true;
                dlg.Filter = "Deployment Report|*.xml";
                dlg.Title = "Select a Tzunami Deployment Report";

                if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {

                    List<Futajma.MigrationStudio.LiveLinkImporter.DeploymentReport.DeploymentReportImportStatus> statusList = new List<Futajma.MigrationStudio.LiveLinkImporter.DeploymentReport.DeploymentReportImportStatus>();

                    var importer = new Futajma.MigrationStudio.LiveLinkImporter.DeploymentReport.DeploymentReportImporter();

                    targetTreeView.BeginUpdate();

                    importer.ImportDeploymentReport(dlg.FileName, targetTreeView, version, statusList);

                    if (MessageBox.Show("Deployment report import done. Do you want to save the logfile ? ", "Log file", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                    {
                        SaveFileDialog saveDlg = new SaveFileDialog();
                        saveDlg.RestoreDirectory = true;
                        saveDlg.Filter = "Logfile|*.txt";
                        saveDlg.Title = "Save Log file";

                        if (saveDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            using (var sw = new StreamWriter(saveDlg.FileName, false))
                            {
                                foreach (var item in statusList)
                                {
                                    sw.Write(string.Format("{0} [{1}]{2}", item.Message, item.SourceUrl, Environment.NewLine));
                                }
                            }
                            MessageBox.Show("Log file saved", "Information");
                        }
                    }
                }
            }
            finally
            {
                targetTreeView.EndUpdate();
            }
        }
    }
}
